package com.seed.core.converter;

import cn.hutool.core.util.StrUtil;
import com.seed.core.action.*;
import com.seed.core.configuration.ActionConfiguration;
import com.seed.core.configuration.ActionConfiguration1;
import com.seed.core.enumeration.ActionType;
import com.seed.core.enumeration.StatType;
import com.seed.core.pojo.seed.Stat;
import com.seed.util.StrKit;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

public class ActionConverter {

    public static Action toAction(ActionConfiguration1 configuration) {
        ActionType type = configuration.getType();
        if(type == null) throw new RuntimeException("【action.type】没有配置");

        return switch (type) {
            case page -> toPageAction(configuration);
            case save, saveBatch -> toSaveAction(configuration);
            case update, updateBatch -> toUpdateAction(configuration);
            case detail -> toDetailAction(configuration);
            case get, getBatch -> toGetAction(configuration);
            case set, setBatch -> toSetAction(configuration);
            case remove, removeBatch -> toRemoveAction(configuration);
            case stat -> toStatAction(configuration);
            case importExcel -> null;
            case exportExcel -> null;
        };
    }

    public static ActionConfiguration1 toFront(ActionConfiguration1 configuration) {
        ActionConfiguration1 ret = new ActionConfiguration1();
        ret.setType(configuration.getType());
        ret.setElements(configuration.getElements());
        ret.setSeedName(configuration.getSeedName());

//        ret.setDeclare(declare);
//        ret.setDeclareValue(declareValue);
//        ret.setDeclares(declares);
//        if(searches != null) {
//            List<String> frontSearches = new ArrayList<>();
//            for(String search: searches) {
//                String[] items = StrKit.cutInTwo(search, '=', false);
//                if(StrUtil.isBlank(items[1])) frontSearches.add(search);
//            }
//            ret.setSearches(frontSearches.toArray(new String[0]));
//        }
//        if(orders != null) {
//            List<String> frontOrders = new ArrayList<>();
//            for(String order: orders) {
//                String[] items = StrKit.cutInTwo(order, '=', false);
//                if(StrUtil.isBlank(items[1])) frontOrders.add(order);
//            }
//            ret.setOrders(frontOrders.toArray(new String[0]));
//        }
//
//        ret.setStats(stats);

        ret.setCheckLogin(configuration.getCheckLogin());
        ret.setCheckAction(configuration.getCheckAction());
//        ret.setUseKeyword(useKeyword);
//        ret.setConfirm(confirm);

//        ret.setPosition(position);
        ret.setMode(configuration.getMode());
        ret.setLabel(configuration.getLabel());
        ret.setComment(configuration.getComment());
        ret.setComponent(configuration.getComponent());
        ret.setLayout(configuration.getLayout());
        ret.setComponentProps(configuration.getComponentProps());
        ret.setPopupProps(configuration.getPopupProps());

        ret.setIcon(configuration.getIcon());
        ret.setColor(configuration.getColor());
        ret.setSize(configuration.getSize());
        ret.setHoverColor(configuration.getHoverColor());

        ret.setAffix(configuration.getAffix());
        ret.setHidden(configuration.getHidden());
        ret.setBreadcrumb(configuration.getBreadcrumb());
        ret.setNoTagsView(configuration.getNoTagsView());

        return ret;
    }

    private static PageAction toPageAction(ActionConfiguration1 configuration) {
        PageAction action = new PageAction();
        setBase(action, configuration);

        Map<String, Object> params = configuration.getParams();
        Object declaresObj = params.get("declares");
        if(declaresObj != null) action.setDeclares(List.of(to(declaresObj)));

        Object searchesObj = params.get("searches");
        if(searchesObj != null) action.setSearches(List.of(to(searchesObj)));

        Object ordersObj = params.get("orders");
        if(ordersObj != null) action.setOrders(List.of(to(ordersObj)));

        action.setStats(toStats(params));

        return action;
    }

    private static SaveAction toSaveAction(ActionConfiguration1 configuration) {
        SaveAction action = new SaveAction();
        setBase(action, configuration);

        Map<String, Object> params = configuration.getParams();
        Object declaresObj = params.get("declares");
        if(declaresObj != null) action.setDeclares(List.of(to(declaresObj)));

        return action;
    }

    private static UpdateAction toUpdateAction(ActionConfiguration1 configuration) {
        UpdateAction action = new UpdateAction();
        setBase(action, configuration);

        Map<String, Object> params = configuration.getParams();
        Object declaresObj = params.get("declares");
        if(declaresObj != null) action.setDeclares(List.of(to(declaresObj)));

        return action;
    }

    private static DetailAction toDetailAction(ActionConfiguration1 configuration) {
        DetailAction action = new DetailAction();
        setBase(action, configuration);

        Map<String, Object> params = configuration.getParams();
        Object declaresObj = params.get("declares");
        if(declaresObj != null) action.setDeclares(List.of(to(declaresObj)));

        return action;
    }

    private static GetAction toGetAction(ActionConfiguration1 configuration) {
        GetAction action = new GetAction();
        setBase(action, configuration);

        Map<String, Object> params = configuration.getParams();
        Object obj = params.get("declare");
        if(obj != null) action.setDeclare((String) obj);

        return action;
    }

    private static SetAction toSetAction(ActionConfiguration1 configuration) {
        SetAction action = new SetAction();
        setBase(action, configuration);

        Map<String, Object> params = configuration.getParams();
        if(params == null) throw new RuntimeException("请配置【params】");

        Object declare = params.get("declare");
        if(declare != null) action.setDeclare((String) declare);

        Object value = params.get("value");
        if(value != null) action.setValue((String) value);

        return action;
    }

    private static RemoveAction toRemoveAction(ActionConfiguration1 configuration) {
        RemoveAction action = new RemoveAction();
        setBase(action, configuration);

        return action;
    }

    private static StatAction toStatAction(ActionConfiguration1 configuration) {
        StatAction action = new StatAction();
        setBase(action, configuration);

        Map<String, Object> params = configuration.getParams();
        Object declaresObj = params.get("declares");
        if(declaresObj != null) action.setDeclares(List.of(to(declaresObj)));

        Object searchesObj = params.get("searches");
        if(searchesObj != null) action.setSearches(List.of(to(searchesObj)));

        action.setStats(toStats(params));

        return action;
    }

    private static void setBase(Action action, ActionConfiguration1 configuration) {
        action.setSeedName(configuration.getSeedName());
        action.setCheckLogin(configuration.getCheckLogin());
        action.setCheckAction(configuration.getCheckAction());
    }

    @SuppressWarnings("unchecked")
    private static String[] to(Object obj) {
        if(obj == null) return null;

        if(obj instanceof List) return ((List<String>) obj).toArray(String[]::new);
        if(obj instanceof String s) return Stream.of(s.split(",")).map(String::trim).toArray(String[]::new);
        if(obj.getClass().isArray()) return (String[]) obj;

        throw new RuntimeException("格式错误");
    }

    @SuppressWarnings("unchecked")
    private static Map<String, Stat> toStats(Map<String, Object> params) {
        if(params == null) return null;

        Object obj = params.get("stats");
        if(obj == null) return null;

        if(!(obj instanceof Map)) throw new RuntimeException("【params.stats】格式错误");

        Map<String, Object> map = (Map<String, Object>) obj;
        Map<String, Stat> stats = new HashMap<>();
        for(Map.Entry<String, Object> entry: map.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if(value == null) continue;

            Stat stat = new Stat();
            stat.setName(key);

            Map<String, String> statMap = new HashMap<>();
            if(value instanceof Map) {
                statMap = (Map<String, String>) value;
            } else if(value instanceof String s) { // 形如：a=b, c=d
                for(String item: s.split(",")) {
                    String[] keyValue = StrKit.cutInTwo(item.trim(), '=', false);
                    statMap.put(keyValue[0], keyValue[1]);
                }
            } else if(value.getClass().isArray()) {
                String[] items = (String[]) obj;
                for(String item: items) {
                    String[] keyValue = StrKit.cutInTwo(item.trim(), '=', false);
                    statMap.put(keyValue[0], keyValue[1]);
                }
            } else {
                throw new RuntimeException("格式错误");
            }

            stat.setType(StatType.valueOf(statMap.get("type")));
            stat.setDeclare(statMap.get("declare"));
            stat.setSearches(to(statMap.get("searches")));

            stats.put(key, stat);
        }

        return stats;
    }
}
